#include "gamewidget.h"
#include <QDebug>

GameWidget::GameWidget(GameSettingsWidget *settings,QWidget *parent, NetworkModule *networkModule) : QWidget(parent){
    QGraphicsScene *characterScene = new QGraphicsScene();
    characterScene->setSceneRect(-480.0, -270.0, 960.0, 540.0);

    layout = new QGridLayout(this);
    noise=new Noise(INT_MAX);
    gameSettings = settings;

    theNetworkModule = networkModule;
    theSinglePlayerModule = new SinglePlayerModule(100,noise,0,MEDIUM,NORMAL,MODERATE,MODERATE,this);
    theModel=theSinglePlayerModule->getModel();

    theTiltWidget=new TiltWidget(theModel, characterScene,noise, this);

    layout->addWidget(theTiltWidget,0,0,10,10,Qt::AlignCenter);

    startGameButton = 0;

    timer=new QTimer();
    timer->setInterval(100);

    backToMenu = new QPushButton(this);
    backToMenu->setText(tr("Back"));
    backToMenu->setMinimumSize(150,60);
    backToMenu->setMaximumSize(200,60);
    backToMenu->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Maximum);
    backToMenu->setStyleSheet(QString::fromUtf8("QPushButton{\nborder:3px solid #78846a;\nbackground-color:#a5b592;\ncolor:#fff;\n}"));
    layout->addWidget(backToMenu,10,8,1,1,Qt::AlignCenter);

    theTiltWidget->setFocus();
    connect(backToMenu,SIGNAL(clicked()),this,SIGNAL(backClicked()));

    init = false;
}

bool GameWidget::switchToNetworkVersion(){
    if(startGameButton != 0 || !init){
        layout->removeWidget(startGameButton);
        delete startGameButton;
        disconnect(timer,SIGNAL(timeout()),this,SLOT(synchedUpdatesSingleGame()));
        disconnect(theSinglePlayerModule,SIGNAL(win(bool,int)),theTiltWidget,SLOT(winGame(bool,int)));
        disconnect(theSinglePlayerModule,SIGNAL(win(bool,int)),this,SLOT(announceResult(bool,int)));
        disconnect(theSinglePlayerModule,SIGNAL(opponentAt(float)),theModel,SLOT(setOpponentPosition(float)));

        init = true;
        return true;
    }
    else return false;
}

void GameWidget::synchedUpdatesMultiplayerGame(){
    theModel->updateState();
    theTiltWidget->updateScreen();
}

void GameWidget::startGameMultiplayer(){
    if(theModel != 0)
        delete theModel;

    if(timer != 0 && timer != theNetworkModule->getTimer())
        delete timer;

    timer = theNetworkModule->getTimer();

    theModel = theNetworkModule->getModel();
    theTiltWidget->setModel(theModel);

    connect(timer,SIGNAL(timeout()),this,SLOT(synchedUpdatesMultiplayerGame()));
    connect(theNetworkModule,SIGNAL(win(bool,int)),theTiltWidget,SLOT(winGame(bool,int)));
    connect(theNetworkModule,SIGNAL(win(bool,int)),this,SLOT(announceResult(bool,int)));
    connect(theNetworkModule,SIGNAL(opponentAt(float)),theModel,SLOT(setOpponentPosition(float)));

    theTiltWidget->updateScreen();
    backToMenu->hide();
    timer->start(100);
}

bool GameWidget::switchToSingleGameVersion(){
    if(startGameButton == 0){
        timer = new QTimer(this);
        timer->setInterval(100);

        disconnect(theModel,SIGNAL(playerPosition(float)),theNetworkModule,SLOT(updatePositions(float)));
        disconnect(timer,SIGNAL(timeout()),this,SLOT(synchedUpdatesSingleGame()));
        disconnect(theNetworkModule,SIGNAL(win(bool,int)),theTiltWidget,SLOT(winGame(bool,int)));
        disconnect(theNetworkModule,SIGNAL(win(bool,int)),this,SLOT(announceResult(bool,int)));
        disconnect(theNetworkModule,SIGNAL(opponentAt(float)),theModel,SLOT(setOpponentPosition(float)));

        startGameButton = new QPushButton(this);
        startGameButton->setText(tr("Play"));
        startGameButton->setMinimumSize(150,60);
        startGameButton->setMaximumSize(200,60);
        startGameButton->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Maximum);
        startGameButton->setStyleSheet(QString::fromUtf8("QPushButton{\nborder:3px solid #78846a;\nbackground-color:#a5b592;\ncolor:#fff;\n}"));
        layout->addWidget(startGameButton,10,9,1,1,Qt::AlignCenter);

        connect(timer,SIGNAL(timeout()),this,SLOT(synchedUpdatesSingleGame()));
        connect(startGameButton,SIGNAL(clicked()),this,SLOT(startGame()));

        init = true;
        return true;
    }
    else return false;
}

void GameWidget::synchedUpdatesSingleGame(){
    theSinglePlayerModule->simulateOpponentMovement();
    theModel->updateState();
    theTiltWidget->updateScreen();
}

void GameWidget::announceResult(bool win, int time){
    if(win)
        qDebug()<<"Won With Opponent Time "<<(time/1000)<<" seconds!";
    else
        qDebug()<<"Lost With Opponent Time "<<(time/1000)<<" seconds!";

    timer->stop();

    backToMenu->show();
    if(startGameButton!=0)
        startGameButton->show();
}

void GameWidget::startGame(){
    int mapLength = gameSettings->getMapLengthSetting();
    int movementSpeed = gameSettings->getMovementSpeedSetting();
    int falldownPenalty = gameSettings->getFalldownPenaltySetting();
    int difficulty = gameSettings->getMapDifficultySetting();

    if(theSinglePlayerModule!=0)
        delete theSinglePlayerModule;

    if(theModel!=0)
        delete theModel;

    theSinglePlayerModule=new SinglePlayerModule(100,noise,20,mapLength,movementSpeed,falldownPenalty,difficulty,this);
    theModel=theSinglePlayerModule->getModel();

    theTiltWidget->setModel(theModel);
    theTiltWidget->updateScreen();

    connect(theSinglePlayerModule,SIGNAL(win(bool,int)),theTiltWidget,SLOT(winGame(bool,int)));
    connect(theSinglePlayerModule,SIGNAL(win(bool,int)),this,SLOT(announceResult(bool,int)));
    connect(theSinglePlayerModule,SIGNAL(opponentAt(float)),theModel,SLOT(setOpponentPosition(float)));

    timer->start();
    backToMenu->hide();
    startGameButton->hide();
}
